Matplotlib

  • Python 2D plotting library which produces figures in many formats and interactive environments.
  • Tries to make easy things easy and hard things possible.
  • You can generate plots, histograms, power spectra, bar charts, errorcharts, scatterplots, etc., with just a few lines of code.
  • Check the Matplotlib gallery.
  • For simple plotting the pyplot module provides a MATLAB-like interface, particularly when combined with IPython.
  • Matplotlib provides a set of functions familiar to MATLAB users.

In this notebook we use some numpy command that will be explain more precisely later.

Line Plots

  • np.linspace(0,1,10) return 10 evenly spaced values over $[0,1]$.
In [1]:
%matplotlib inline
# inline can be replaced by notebook to get interactive plots
import numpy as np
import matplotlib.pyplot as plt
In [2]:
plt.rcParams['figure.figsize'] = (10.0, 6.0) # set figures display bigger
x = np.linspace(- 5*np.pi,5*np.pi,100) 
plt.plot(x,np.sin(x)/x);
In [3]:
plt.plot(x,np.sin(x)/x,x,np.sin(2*x)/x);

If you have a recent Macbook with a Retina screen, you can display high-resolution plot outputs. Running the next cell will give you double resolution plot output for Retina screens.

Note: the example below won’t render on non-retina screens

In [4]:
%config InlineBackend.figure_format = 'retina'
In [5]:
# red, dot-dash, triangles and blue, dot-dash, bullet
plt.plot(x,np.sin(x)/x, 'r-^',x,np.sin(2*x)/x, 'b-o');

Simple Scatter Plot

In [6]:
x = np.linspace(-1,1,50)
y = np.sqrt(1-x**2)
plt.scatter(x,y);

Colormapped Scatter Plot

In [7]:
theta = np.linspace(0,6*np.pi,50) # 50 steps from 0 to 6 PI
size = 30*np.ones(50) # array with 50 values set to 30
z = np.random.rand(50) # array with 50 random values in [0,1]
x = theta*np.cos(theta)
y = theta*np.sin(theta)
plt.scatter(x,y,size,z)
plt.colorbar();

Change Colormap

In [8]:
fig = plt.figure() # create a figure
ax = fig.add_subplot(1, 1, 1) # add a single plot
ax.scatter(x,y,size,z,cmap='jet');
ax.set_aspect('equal', 'datalim')

colormaps in matplotlib documentation.

Multiple Figures

In [9]:
plt.figure()
plt.plot(x)
plt.figure()
plt.plot(z,'ro');

Multiple Plots Using subplot

In [10]:
plt.subplot(1,2,1) # 1 row 1, 2 columns, active plot number 1
plt.plot(x,'b-*')
plt.subplot(1,2,2) # 1 row 1, 2 columns, active plot number 2
plt.plot(z,'ro');

Legends

  • Legends labels with plot
In [11]:
theta =np.linspace(0,4*np.pi,200)
plt.plot(np.sin(theta), label='sin')
plt.plot(np.cos(theta), label='cos')
plt.legend();
  • Labelling with legend
In [12]:
plt.plot(np.sin(theta))
plt.plot(np.cos(theta)**2)
plt.legend(['sin','$\cos^2$']);

Titles and Axis Labels

In [13]:
plt.plot(theta,np.sin(theta))
plt.xlabel('radians from 0 to $4\pi$')
plt.ylabel('amplitude');
In [14]:
t = np.arange(0.01, 20.0, 0.01)

plt.subplot(121) 
plt.semilogy(t, np.exp(-t/5.0))
plt.title('semilogy')
plt.grid(True)

plt.subplot(122,fc='y') 
plt.semilogx(t, np.sin(2*np.pi*t))
plt.title('semilogx')
plt.grid(True)

Plot Grid and Save to File

In [15]:
theta = np.linspace(0,2*np.pi,100)
plt.plot(np.cos(theta),np.sin(theta))
plt.grid();
In [16]:
plt.savefig('circle.png');
%ls *.png
circle.png
<Figure size 720x432 with 0 Axes>

Histogram

In [17]:
from numpy.random import randn
plt.hist(randn(1000));

Change the number of bins and supress display of returned array with ;

In [18]:
plt.hist(randn(1000), 30);

Contour Plot

In [19]:
x = y = np.arange(-2.0*np.pi, 2.0*np.pi+0.01, 0.01)
X, Y = np.meshgrid(x, y)
Z = np.sin(X)*np.cos(Y)

plt.contourf(X, Y, Z,cmap=plt.cm.hot);

Image Display

In [20]:
img = plt.imread("https://hackage.haskell.org/package/JuicyPixels-extra-0.1.0/src/data-examples/lenna.png")
plt.imshow(img)
Out[20]:
<matplotlib.image.AxesImage at 0x7fb6485bb7c0>

figure and axis

Best method to create a plot with many components

In [21]:
fig = plt.figure()
axis = fig.add_subplot(111, aspect='equal',
                     xlim=(-2, 2), ylim=(-2, 2))

state = -0.5 + np.random.random((50, 4))
state[:, :2] *= 3.9
bounds = [-1, 1, -1, 1]

particles = axis.plot(state[:,0], state[:,1], 'bo', ms=6)
rect = plt.Rectangle(bounds[::2],
                     bounds[1] - bounds[0],
                     bounds[3] - bounds[2],
                     ec='r', lw=2, fc='none')
axis.grid()
axis.add_patch(rect)
axis.text(-0.5,1.1,"BOX")
Out[21]:
Text(-0.5, 1.1, 'BOX')

Exercises

Recreate the image my_plots.png using the delicate_arch.png file in images directory.

Alternatives

  • bqplot : Jupyter Notebooks, Interactive.
  • seaborn : Statistics.
  • toyplot : Nice graphes.
  • bokeh : Interactive and Server mode.
  • pygal : Charting
  • Altair : Data science
  • plot.ly : Data science and interactive
  • Mayavi: 3D
  • YT: Astrophysics (volume rendering, contours, particles).
  • VisIt: Powerful, easy to use but heavy.
  • Paraview: The most-used visualization application. Need high learning effort.
  • PyVista: 3D plotting and mesh analysis through a streamlined interface for the Visualization Toolkit (VTK)
  • Yellowbrick : Yellowbrick: Machine Learning Visualization
In [22]:
#example from Filipe Fernandes
#http://nbviewer.jupyter.org/gist/ocefpaf/9730c697819e91b99f1d694983e39a8f
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import animation

g = 9.81
denw = 1025.0  # Seawater density [kg/m**3].
sig = 7.3e-2  # Surface tension [N/m].
a = 1.0  # Wave amplitude [m].

L, h = 100.0, 50.0  # Wave height and water column depth.
k = 2 * np.pi / L
omega = np.sqrt((g * k + (sig / denw) * (k**3)) * np.tanh(k * h))
T = 2 * np.pi / omega
c = np.sqrt((g / k + (sig / denw) * k) * np.tanh(k * h))

# We'll solve the wave velocities in the `x` and `z` directions.
x, z = np.meshgrid(np.arange(0, 160, 10), np.arange(0, -80, -10),)
u, w = np.zeros_like(x), np.zeros_like(z)


def compute_vel(phase):
    u = a * omega * (np.cosh(k * (z+h)) / np.sinh(k*h)) * np.cos(k * x - phase)
    w = a * omega * (np.sinh(k * (z+h)) / np.sinh(k*h)) * np.sin(k * x - phase)
    mask = -z > h
    u[mask] = 0.0
    w[mask] = 0.0
    return u, w


def basic_animation(frames=91, interval=30, dt=0.3):
    fig = plt.figure(figsize=(8, 6))
    ax = plt.axes(xlim=(0, 150), ylim=(-70, 10))

    # Animated.
    quiver = ax.quiver(x, z, u, w, units='inches', scale=2)
    ax.quiverkey(quiver, 120, -60, 1,
                 label=r'1 m s$^{-1}$',
                 coordinates='data')
    line, = ax.plot([], [], 'b')

    # Non-animated.
    ax.plot([0, 150], [0, 0], 'k:')
    ax.set_ylabel('Depth [m]')
    ax.set_xlabel('Distance [m]')
    text = (r'$\lambda$ = %s m;  h = %s m;  kh = %2.3f;  h/L = %s' %
            (L, h, k * h, h/L))
    ax.text(10, -65, text)
    time_step = ax.text(10, -58, '')
    line.set_data([], [])

    def init():
        return line, quiver, time_step

    def animate(i):
        time = i * dt
        phase = omega * time
        eta = a * np.cos(x[0] * k - phase)
        u, w = compute_vel(phase)
        quiver.set_UVC(u, w)
        line.set_data(x[0], 5 * eta)
        time_step.set_text('Time = {:.2f} s'.format(time))
        return line, quiver, time_step

    return animation.FuncAnimation(fig, animate, init_func=init,
                                   frames=frames, interval=interval)
In [23]:
from IPython.display import HTML

HTML(basic_animation(dt=0.3).to_jshtml())
Out[23]: